package scu.maqiang.mixed;

import scu.maqiang.fes.BVPType;
import scu.maqiang.fes.FES2T3Mix_RT0P0;
import scu.maqiang.mesh.Mesh2T3;
import scu.maqiang.mesh.T3Type;
import scu.maqiang.numeric.*;

public class EdgeNumbers {
    public static void main(String[] args) {
//        Mesh2T3 mesh = new Mesh2T3().square2D(2, 2, T3Type.Left);
//        SIMatrix edges = mesh.renumberingEdges();
//////        mesh.displayNodes();
//////        mesh.displayElements();
//////        mesh.displayBoundarys();
//        System.out.println(edges);
//        var edgeSet = mesh.extractEdgesFromElements();
//        System.out.println(edgeSet.size());
//        for(var ele: edgeSet) {
//            System.out.println(Arrays.toString(ele.getIntSet()));
//        }
//        System.out.println(edgeSet.contains(new UnorderIntArray(new int[]{1, 0})));
        firstMixFEM();
    }

    public static void firstMixFEM() {
//        double[][] nodes = {
//                {0, 0},
//                {1, 0},
//                {1, 1},
//                {0, 1},
//                {-1, 1},
//                {-1, 0},
//                {-1, -1},
//                {0, -1}
//        };
//        int[][] elements = {
//                {1, 2, 3},
//                {1, 3, 4},
//                {1, 4, 5},
//                {1, 5, 6},
//                {1, 6, 7},
//                {1, 7, 8}
//        };

        Mesh2T3 mesh = new Mesh2T3();
        //mesh.constructMesh(nodes, elements, false);
        mesh.square2D(100, 100, T3Type.Left);
//        mesh.displayNodes();
//        mesh.displayElements();
//        mesh.displayBoundarys();

        FES2T3Mix_RT0P0 mixFes = new FES2T3Mix_RT0P0(mesh);
        int nDof = mixFes.GetNdof();
        SRMatrix A = new SRMatrix(nDof);
        double[] RHS = new double[nDof];
        mixFes.assembleMixedStiff(1.0, BVPType.COMMON, A);
        //A.sort();
        //System.out.println(A);
        mixFes.assembleMixSource(0.0, 1.0, RHS, 1, 2, 3, 4);
        //System.out.println(Arrays.toString(RHS));

        DirectSSolver solver = new DirectSSolver(A);
        double[] x = solver.LUSolve(RHS, 1, 1.0e-10);

        int nEdge = mixFes.getNumberOfEdges();
        double[] elementSol = new double[mesh.getNt()];
        for(int i = 0; i < mesh.getNt(); i++) {
            elementSol[i] = x[nEdge + i];
        }
        System.out.println("min: " + MVO.min(elementSol) + " max: " + MVO.max(elementSol));
        //System.out.println("");
        //System.out.println(Arrays.toString(x));
        mesh.toTecplotP0("mixSolutionP0.dat", elementSol);
        double[] u = new double[mesh.getNv()];
        double[] ux = new double[mesh.getNv()];
        double[] uy = new double[mesh.getNv()];
        mixFes.extractSolution(x, ux, uy, u);
        System.out.println("min: " + MVO.min(ux) + " max: " + MVO.max(ux));
        System.out.println("min: " + MVO.min(uy) + " max: " + MVO.max(uy));
        System.out.println("min: " + MVO.min(u) + " max: " + MVO.max(u));
        mesh.toTecplot("mixedSolutions.dat", new double[][]{u, ux, uy});
    }
}
